package com.maixy.studyonlineapi.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.maixy.studyonlineapi.entity.Activity;
import com.maixy.studyonlineapi.entity.Team;
import com.maixy.studyonlineapi.entity.TeamUser;
import com.maixy.studyonlineapi.entity.User;
import com.maixy.studyonlineapi.enums.TeamRoleEnum;
import com.maixy.studyonlineapi.exceptions.TipException;
import com.maixy.studyonlineapi.mapper.TeamMapper;
import com.maixy.studyonlineapi.utils.DataTypeUtil;
import com.maixy.studyonlineapi.utils.RandomUtil;
import com.maixy.studyonlineapi.view.TeamView;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Classname TeamService
 * @Description TODO
 * @Date 2020/11/1 19:30
 * @Author by maixy
 */
@Service
public class TeamService extends BaseMPlusService<Team, Long>{
    private final TeamMapper teamMapper;

    @Resource
    private TeamUserService teamUserService;

    @Resource
    private ActivityService activityService;

    @Resource
    private UserService userService;

    @Resource
    private AuthService authService;

    protected TeamService(TeamMapper teamMapper) {
        super(Team.class, teamMapper);
        this.teamMapper = teamMapper;
    }

    /**
     * 创建团队
     * @param userId 团队发起人
     * @return java.lang.Long
     */
    public Long add(Long userId) {
        Team team = new Team();
        team.setCreateBy(userId);
        team.setHasDelete(false);
        team.setCreateTime(System.currentTimeMillis());
        team = create(team);
        return team.getId();
    }

    /**
     * 是否是超级管理员
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.Boolean
     */
    public Boolean isSuperManager(Long teamId, Long userId) {
        Team team = findById(teamId);
        if (null == team || team.getHasDelete()) {
            throw new TipException("团队不存在或已被删除");
        }
        return team.getCreateBy().equals(userId);
    }

    /**
     * 是否是团队成员
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.Boolean
     */
    public Boolean isManager(Long teamId, Long userId) {
        Team team = findById(teamId);
        if (null == team || team.getHasDelete()) {
            throw new TipException("团队不存在或已被删除");
        }
        TeamUser teamUser = teamUserService.findTeamUserByUserIdAndTeamId(teamId, userId);
        return null != teamUser && !teamUser.getHasDelete();
    }


    /**
     * 是否有权限执行团队权力
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.Boolean
     */
    public Boolean hasPower(Long teamId, Long userId) {
        Team team = findById(teamId);
        if (null == team || team.getHasDelete()) {
            throw new TipException("团队不存在或已被删除");
        }
        if (team.getCreateBy().equals(userId)) {
            return true;
        }else {
            TeamUser teamUser = teamUserService.findTeamUserByUserIdAndTeamId(teamId, userId);
            return null != teamUser && !teamUser.getHasDelete();
        }
    }

    /**
     * 在活动中是否有权限执行团队权力
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.Boolean
     */
    public Boolean hasActivityPower(Long teamId, Long userId, Long activityId) {
        Team team = findById(teamId);
        if (null == team || team.getHasDelete()) {
            throw new TipException("团队不存在或已被删除");
        }
        Activity activity = activityService.findById(activityId);
        if (null == activity || activity.getHasDelete()) {
            throw new TipException("班级不存在或已被删除");
        }
        return team.getCreateBy().equals(activity.getCreateBy()) && hasPower(teamId, userId);
    }

    /**
     * 获得超级管理员的id
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.Long
     */
    public Long getSuperManagerUserId(Long teamId, Long userId) {
        if (hasPower(teamId, userId)) {
            Team team = findById(teamId);
            return team.getCreateBy();
        }else {
            return userId;
        }
    }

    /**
     * 已加入的团队列表
     *
     * @param userId 用户id
     * @return List<com.maixy.studyonlineapi.view.TeamView>
     */
    public List<TeamView> getTeamList(Long userId) {
        Team team = findTeamByUserId(userId);
        List<TeamView> teamViewList = Lists.newArrayList();
        if (null != team && !team.getHasDelete()) {
            teamViewList.add(convert(team, userId));
        }

        List<TeamUser> teamUserList = teamUserService.findTeamUserListByUserId(userId);
        for (TeamUser teamUser : teamUserList) {
            Team tempTeam = findById(teamUser.getTeamId());
            if (null != tempTeam && !tempTeam.getHasDelete()) {
                teamViewList.add(convert(tempTeam, userId));
            }
        }
        return teamViewList;
    }

    /**
     * 团队视图转换
     *
     * @param team 团队实体
     * @param userId 用户id
     * @return com.maixy.studyonlineapi.view.TeamView
     */
    public TeamView convert(Team team, Long userId) {
        TeamView view = new TeamView();
        view.setTeamId(DataTypeUtil.getStr(team.getId()));
        if (userId.equals(team.getCreateBy())) {
            view.setTeamRole(TeamRoleEnum.SUPER_MANAGER.getCode());
            if (null == team.getInviteCode() || StringUtils.isBlank(team.getInviteCode())) {
                team.setInviteCode(RandomUtil.randomStr(20));
                team.setUpdateBy(userId);
                team.setUpdateTime(System.currentTimeMillis());
                update(team);
            }
            view.setInviteCode(team.getInviteCode());
        } else {
            view.setTeamRole(TeamRoleEnum.MANAGER.getCode());
        }
        User user = userService.findById(team.getCreateBy());
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在");
        }
        view.setUserView(userService.convert(user));
        return view;
    }

    /**
     * 查看团队邀请码
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.String
     */
    public String getInviteCode(Long teamId, Long userId) {
        if (!isSuperManager(teamId, userId)) {
            throw new TipException("超级管理员才能查看团队邀请码");
        }
        Team team = findById(teamId);
        if (null == team.getInviteCode() || StringUtils.isBlank(team.getInviteCode())) {
            team.setInviteCode(RandomUtil.randomStr(20));
            team.setUpdateBy(userId);
            team.setUpdateTime(System.currentTimeMillis());
            update(team);
        }
        return team.getInviteCode();
    }

    /**
     * 更新团队邀请码
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @return java.lang.String
     */
    public String updateInviteCode(Long teamId, Long userId) {
        if (!isSuperManager(teamId, userId)) {
            throw new TipException("超级管理员才能查看团队邀请码");
        }
        Team team = findById(teamId);
        team.setInviteCode(RandomUtil.randomStr(20));
        team.setUpdateBy(userId);
        team.setUpdateTime(System.currentTimeMillis());
        update(team);
        return team.getInviteCode();
    }

    /**
     * 加入团队
     *
     * @param userId 用户id
     * @param inviteCode 邀请码
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void joinTeam(Long userId, String inviteCode) {
        Team team = findTeamByInviteCode(inviteCode);
        if (null == team || team.getHasDelete()) {
            throw new TipException("无效的邀请码");
        }
        if (isSuperManager(team.getId(), userId)) {
            throw new TipException("您已经是团队的超级管理员");
        }

        if (isManager(team.getId(), userId)) {
            throw new TipException("您已经是团队的管理员");
        }

        teamUserService.saveTeamUser(team.getId(), userId);
        //退出所有课程
       // authService.findAuthByTeacherIdAndStudentId(team.getCreateBy(), userId);
    }

    /**
     * 切换团队
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @param currentTeamId 当前团队id
     * @return java.lang.String
     */
    public String exchangeTeam(Long teamId, Long userId, Long currentTeamId) {
        if (teamId.equals(currentTeamId)) {
            throw new TipException("不能切换到一样的团队");
        }
        Team team = findById(currentTeamId);
        if (null == team || team.getHasDelete()) {
            throw new TipException("团队不存在或已被删除");
        }
        if (!hasPower(currentTeamId, userId)) {
            throw new TipException("没有权限");
        }
        return DataTypeUtil.getStr(team.getId());
    }

    /**
     * 根据userId查找发起的团队
     *
     * @param useId 用户id
     * @return com.maixy.studyonlineapi.entity.Team
     */
    public Team findTeamByUserId(Long useId) {
        return teamMapper.selectOne(new QueryWrapper<Team>()
                .lambda()
                .eq(Team::getCreateBy, useId)
                .eq(Team::getHasDelete, false)
                .orderByDesc(Team::getCreateTime)
                .last("limit 1"));
    }

    /**
     * 根据inviteCode查找发起的团队
     *
     * @param inviteCode 邀请码
     * @return com.maixy.studyonlineapi.entity.Team
     */
    public Team findTeamByInviteCode(String inviteCode) {
        return teamMapper.selectOne(new QueryWrapper<Team>()
                .lambda()
                .eq(Team::getInviteCode, inviteCode)
                .eq(Team::getHasDelete, false)
                .orderByDesc(Team::getCreateTime)
                .last("limit 1"));
    }
}
